package cn.taneroom.utils;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

/**
 * 图像处理相关帮助类
 * @author TaneRoom
 * @since 2016年8月2日 下午2:22:55
 */
public class ImageUtil {

	/**
     * 根据设置的宽高等比例压缩图片文件<br> 先保存原文件，再压缩、上传  
     * @param oldFile 源文件地址
     * @param newFile 输出文件地址
     * @param width 输出图片宽度
     * @param height 输出图片高度
     * @throws Exception 强制调用函数捕获异常
     */
    public static void zipImageFile(String sourceFilePath, String targetFilePath, int width, int height) throws Exception {
    	 if (!new File(sourceFilePath).exists()) {    
             throw new RuntimeException("对不起，输出文件不能为空！");
         }
    	 OutputStream os = null;
         try {    
             /** 对服务器上的临时文件进行处理 */    
             Image image = ImageIO.read(new File(sourceFilePath));    
             int w = image.getWidth(null);    
             int h = image.getHeight(null);    
             double bili;    
             if(width>0){    
                 bili=width/(double)w;    
                 height = (int) (h*bili);    
             }else{    
                 if(height>0){    
                     bili=height/(double)h;    
                     width = (int) (w*bili);    
                 }    
             }    
               
             System.out.println(targetFilePath);  
             String subfix = "jpg";  
             subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());  
   
             BufferedImage buffImg = null;   
             if(subfix.equalsIgnoreCase("png")){  
                 buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
             }else{  
                 buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
             }  
   
             //创建画笔对象
             Graphics2D graphics = buffImg.createGraphics();  
             graphics.setBackground(new Color(255,255,255));  
             graphics.setColor(new Color(255,255,255));  
             graphics.fillRect(0, 0, width, height);  
             graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
             graphics.dispose();//销毁画笔对象
             
             os = new FileOutputStream(targetFilePath);
             ImageIO.write(buffImg, subfix, os);    
         } catch (FileNotFoundException e) {    
             e.printStackTrace();    
         } catch (IOException e) {    
             e.printStackTrace();    
         }finally{
        	 if(os != null){
        		 os.close();
        	 }
         }
    }
    
    /**
     * 按设置的宽度高度压缩图片文件<br> 先保存原文件，再压缩、上传  
     * @param oldFile 源文件地址
     * @param newFile 输出文件地址
     * @param width 输出图片宽度
     * @param height 输出图片高度
     * @throws Exception 强制调用函数捕获异常
     */
    public static void zipWidthHeightImageFile(String sourceFilePath,String targetFilePath, int width, int height) throws Exception {    
        if (!new File(sourceFilePath).exists()) {    
            throw new RuntimeException("对不起，输出文件不能为空！");
        }
        OutputStream os = null;
        try {    
            /** 对服务器上的临时文件进行处理 */    
            Image image = ImageIO.read(new File(sourceFilePath));    
              
            System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());  
  
            BufferedImage buffImg = null;   
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            }  
  
            //创建画笔对象
            Graphics2D graphics = buffImg.createGraphics();  
            graphics.setBackground(new Color(255,255,255));  
            graphics.setColor(new Color(255,255,255));  
            graphics.fillRect(0, 0, width, height);  
            graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);    
            graphics.dispose();//销毁画笔对象
            
            os = new FileOutputStream(targetFilePath);
            ImageIO.write(buffImg, subfix, os);
        } catch (FileNotFoundException e) {    
            e.printStackTrace();    
        } catch (IOException e) {    
            e.printStackTrace();    
        }finally{
        	if(os != null){
        		os.close();
        	}
        }  
    }  
    
    /**
     * 给图片添加图片水印、可设置水印图片旋转角度
     * @param srcImgPath 源文件地址
     * @param targerPath 输出文件地址
     * @param iconPath 水印文件地址
     * @param w 水印位置(距右边的距离)
     * @param h 水印位置(距底部的距离)
     * @param alpha 水印透明度
     */
    public static void markImageByIcon(String sourceFilePath,String targetFilePath, 
    		String iconPath, int w, int h, float alpha) {
    	OutputStream os = null;
        try {     
            Image image = ImageIO.read(new File(sourceFilePath)); 
            int height = image.getHeight(null);
            int weight = image.getWidth(null);
            
            System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());  
  
            BufferedImage buffImg = null;   
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);  
            }
            
            //创建画笔对象     
            Graphics2D g = buffImg.createGraphics();
            g.setColor(Color.GRAY);
            g.setBackground(new Color(255,255,255));
    
            //设置对线段的锯齿状边缘处理     
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            //将输出图片先画出来
            g.drawImage(image.getScaledInstance(image.getWidth(null), image.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);     
            //水印图象的路径 水印一般为gif或者png的，这样可设置透明度    
            ImageIcon imgIcon = new ImageIcon(iconPath);     
            //得到Image对象。     
            Image img = imgIcon.getImage();  
            int iconheight = img.getHeight(null);
            int iconWeight = img.getWidth(null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));     
            //表示水印图片的位置     
            g.drawImage(img, weight-w-iconWeight, height-h-iconheight, null);     
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));     
            g.dispose();//销毁画笔对象
            os = new FileOutputStream(targetFilePath);     
            //生成图片     
            ImageIO.write(buffImg, subfix, os);     
        } catch (IOException e) {     
            e.printStackTrace();     
        } finally {     
        	if (null != os){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
        	}     
        }     
    }  
    
    /**
     * 给图片加上文字水印
     * @param sourceFilePath 源文件地址
     * @param targetFilePath 输出文件地址
     * @param markContent 文字内容
     * @param fontType 文字字体
     * @param fontSize 文字大小
     * @param w 文字位置(距左边的距离)
     * @param h 文字位置(距底部的距离)
     * @param color 文字颜色(水印颜色)
     */
	public static void markImageByString(String sourceFilePath, String targetFilePath, String markContent,
			String fontType, int fontSize, int w, int h, Color color) {
		OutputStream os = null;
		try {
			/* 构建要处理的源图片 */
			ImageIcon imageIcon = new ImageIcon(sourceFilePath);
			/* 获取要处理的图片 */
			Image image = imageIcon.getImage();
			// Image可以获得图片的属性信息
			int width = image.getWidth(null);
			int height = image.getHeight(null);
			System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());  
  
            // 为画出与源图片的相同大小的图片（可以自己定义）
            BufferedImage buffImg = null;   
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            }
			
			// 构建2D画笔
			Graphics2D g = buffImg.createGraphics();
			/* 设置2D画笔的画出的文字颜色 */
			g.setColor(color);
			/* 设置2D画笔的画出的文字背景色 */
			g.setBackground(new Color(255, 255, 255));
			/* 画出图片 */
			g.drawImage(image, 0, 0, null);
			/* 对要显示的文字进行处理 */
			AttributedString ats = new AttributedString(markContent);
			Font font = new Font(fontType, Font.PLAIN, fontSize);
			g.setFont(font);
			/* 消除java.awt.Font字体的锯齿 */
			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			/* 添加字体属性 */
			ats.addAttribute(TextAttribute.FONT, font, 0, markContent.length());
			AttributedCharacterIterator iter = ats.getIterator();
			/* 添加水印的文字和设置水印文字出现的内容以及位置 */
			g.drawString(iter, w, height - h);
			/* 对要显示的文字进行处理 */
			g.dispose();// 画笔结束

			os = new FileOutputStream(targetFilePath);
			ImageIO.write(buffImg, subfix, os);
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(os != null){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 等比例压缩并给压缩后的图片加上文字水印
	 * @param sourceFilePath 源文件地址
	 * @param targetFilePath 输出文件地址
	 * @param markContent 文字内容
	 * @param fontType 文字字体
	 * @param fontSize 文字大小
	 * @param w 文字位置(距左边的距离)
	 * @param h 文字位置(距右边的距离)
	 * @param color 文字颜色(水印颜色)
	 * @param width 输出图片宽度
	 * @param height 输出图片高度
	 * @throws Exception 强制调用函数捕获异常
	 */
	public static void zipImageAndMarkString(String sourceFilePath, String targetFilePath, String markContent,
			String fontType, int fontSize, int w, int h, Color color, int width, int height) throws Exception {
		if (sourceFilePath == null) {    
            throw new RuntimeException("对不起，输出文件不能为空！");
        }
		OutputStream os = null;
        try {    
            /** 对服务器上的临时文件进行处理 */    
            Image image = ImageIO.read(new File(sourceFilePath));    
            int imageW = image.getWidth(null);    
            int imageH = image.getHeight(null);    
            double bili;    
            if(width>0){    
                bili=width/(double)imageW;    
                height = (int) (imageH*bili);    
            }else{    
                if(height>0){    
                    bili=height/(double)imageH;    
                    width = (int) (imageW*bili);    
                }    
            }    
              
            System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());  
  
            BufferedImage buffImg = null;
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            }  
  
            Graphics2D graphics = buffImg.createGraphics();  
            graphics.setBackground(new Color(255,255,255));  
            /* 设置2D画笔的画出的文字颜色 */
            graphics.setColor(color);
            graphics.fillRect(0, 0, width, height);  
            graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
            
            /* 对要显示的文字进行处理 */
    		AttributedString ats = new AttributedString(markContent);
    		Font font = new Font(fontType, Font.PLAIN, fontSize);
    		graphics.setFont(font);
    		/* 消除java.awt.Font字体的锯齿 */
    		graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    		/* 设置字体属性 */
    		ats.addAttribute(TextAttribute.FONT, font, 0, markContent.length());
    		AttributedCharacterIterator iter = ats.getIterator();
    		/* 添加水印的文字和设置水印文字出现的内容以及位置 */
    		graphics.drawString(iter, w, height - h);
    		/* 对要显示的文字进行处理 */
    		graphics.dispose();// 画笔结束
    		
    		os = new FileOutputStream(targetFilePath);
            ImageIO.write(buffImg, subfix, os);    
        } catch (FileNotFoundException e) {    
            e.printStackTrace();    
        } catch (IOException e) {    
            e.printStackTrace();    
        } finally {
        	if(os != null){
        		os.close();
        	}
        }
	}

	/**
	 * 等比例压缩并给压缩后的图片加上图片水印
	 * @param sourceFilePath 源文件地址
	 * @param targetFilePath 输出文件地址
	 * @param iconPath 水印文件地址
	 * @param w 水印位置(距右边的距离)
	 * @param h 水印位置(距底部的距离)
	 * @param alpha 水印透明度
	 * @param width 输出图片宽度
	 * @param height 输出图片高度
	 * @throws Exception 强制调用函数捕获异常
	 */
	public static void zipImageAndMarkIcon(String sourceFilePath, String targetFilePath, String iconPath,
			int w, int h, float alpha, int width, int height) throws Exception{
		if (sourceFilePath == null) {    
            throw new RuntimeException("对不起，输出文件不能为空！");
        }
		OutputStream os = null;
        try {    
            /** 对服务器上的临时文件进行处理 */    
            Image image = ImageIO.read(new File(sourceFilePath));    
            int imageW = image.getWidth(null);    
            int imageH = image.getHeight(null);    
            double bili;    
            if(width>0){    
                bili=width/(double)imageW;    
                height = (int) (imageH*bili);    
            }else{    
                if(height>0){    
                    bili=height/(double)imageH;    
                    width = (int) (imageW*bili);    
                }    
            }    
              
            System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());  
  
            BufferedImage buffImg = null; 
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            }  
  
            Graphics2D graphics = buffImg.createGraphics();
            graphics.setColor(Color.GRAY);
            graphics.setBackground(new Color(255,255,255));
            // 设置对线段的锯齿状边缘处理     
            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
            
            // 水印图象的路径 水印一般为gif或者png的，这样可设置透明度    
            ImageIcon imgIcon = new ImageIcon(iconPath);     
            // 得到Image对象
            Image img = imgIcon.getImage();  
            int iconH = img.getHeight(null);
            int iconW = img.getWidth(null);
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));     
            // 表示水印图片的位置     
            graphics.drawImage(img, width-w-iconW, height-w-iconH, null);     
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));     
            graphics.dispose();
            
            os = new FileOutputStream(targetFilePath);
            ImageIO.write(buffImg, subfix, os);
        } catch (FileNotFoundException e) {    
            e.printStackTrace();    
        } catch (IOException e) {    
            e.printStackTrace();    
        } finally {
        	if(os != null){
        		os.close();
        	}
        }
	}
	
	/**
	 * 按指定宽高压缩并给压缩后的图片加上文字水印
	 * @param sourceFilePath 源文件地址
	 * @param targetFilePath 输出文件地址
	 * @param markContent 文字内容
	 * @param fontType 文字字体
	 * @param fontSize 文字大小
	 * @param w 文字位置(距左边的距离)
	 * @param h 文字位置(距底部的距离)
	 * @param color 文字颜色(水印颜色)
	 * @param width 输出图片宽度
	 * @param height 输出图片高度
	 * @throws Exception 强制调用函数捕获异常
	 */
	public static void zipWidthHeightImageAndMarkString(String sourceFilePath, String targetFilePath, String markContent,
			String fontType, int fontSize, int w, int h, Color color, int width, int height) throws Exception{
		if (sourceFilePath == null) {    
            throw new RuntimeException("对不起，输出文件不能为空！");
        }
		OutputStream os = null;
        try {    
            /** 对服务器上的临时文件进行处理 */    
            Image image = ImageIO.read(new File(sourceFilePath));    
              
            System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());     
  
            BufferedImage buffImg = null;   
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            }  
  
            Graphics2D graphics = buffImg.createGraphics();  
            graphics.setBackground(new Color(255,255,255));  
            /* 设置2D画笔的画出的文字颜色 */
            graphics.setColor(color);
            graphics.fillRect(0, 0, width, height);  
            graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
            
            /* 对要显示的文字进行处理 */
    		AttributedString ats = new AttributedString(markContent);
    		Font font = new Font(fontType, Font.PLAIN, fontSize);
    		graphics.setFont(font);
    		/* 消除java.awt.Font字体的锯齿 */
    		graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    		/* 设置字体属性 */
    		ats.addAttribute(TextAttribute.FONT, font, 0, markContent.length());
    		AttributedCharacterIterator iter = ats.getIterator();
    		/* 添加水印的文字和设置水印文字出现的内容以及位置 */
    		graphics.drawString(iter, w, height - h);
    		/* 对要显示的文字进行处理 */
    		graphics.dispose();// 画笔结束
    		
    		os = new FileOutputStream(targetFilePath);
            ImageIO.write(buffImg, subfix, os);    
        } catch (FileNotFoundException e) {    
            e.printStackTrace();    
        } catch (IOException e) {    
            e.printStackTrace();    
        } finally {
        	if(os != null){
        		os.close();
        	}
        }
	}
	
	/**
	 * 按指定宽高压缩并给压缩后的图片加上图片水印
	 * @param sourceFilePath 源文件地址
	 * @param targetFilePath 输出文件地址
	 * @param iconPath 水印文件地址
	 * @param w 水印位置(距右边的距离)
	 * @param h 水印位置(距底部的距离)
	 * @param alpha 水印透明度
	 * @param width 输出图片宽度
	 * @param height 输出图片高度
	 * @throws Exception 强制调用函数捕获异常
	 */
	public static void zipWidthHeightImageAndMarkIcon(String sourceFilePath, String targetFilePath, String iconPath,
			int w, int h, float alpha, int width, int height) throws Exception{
		if (sourceFilePath == null) {    
            throw new RuntimeException("对不起，输出文件不能为空！");
        }
		OutputStream os = null;
        try {    
            /** 对服务器上的临时文件进行处理 */    
            Image image = ImageIO.read(new File(sourceFilePath));    
              
            System.out.println(targetFilePath);  
            String subfix = "jpg";  
            subfix = targetFilePath.substring(targetFilePath.lastIndexOf(".")+1,targetFilePath.length());    
  
            BufferedImage buffImg = null;   
            if(subfix.equalsIgnoreCase("png")){  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
            }else{  
                buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
            }  
  
            Graphics2D graphics = buffImg.createGraphics(); 
            graphics.setColor(Color.GRAY);
            graphics.setBackground(new Color(255,255,255));
            // 设置对线段的锯齿状边缘处理     
            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics.drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
            
            // 水印图象的路径 水印一般为gif或者png的，这样可设置透明度    
            ImageIcon imgIcon = new ImageIcon(iconPath);     
            // 得到Image对象
            Image img = imgIcon.getImage();  
            int iconH = img.getHeight(null);
            int iconW = img.getWidth(null);
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));     
            // 表示水印图片的位置 
            graphics.drawImage(img, width-w-iconW, height-w-iconH, null);     
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));     
            graphics.dispose();   
            os = new FileOutputStream(targetFilePath);
            ImageIO.write(buffImg, subfix, os);
        } catch (FileNotFoundException e) {    
            e.printStackTrace();    
        } catch (IOException e) {    
            e.printStackTrace();    
        } finally {
        	if(os != null){
        		os.close();
        	}
        }
	}
	
	public static void main(String[] args) {
		String sourceFilePath = "src/sources/old.png";
		String targetFilePath = "C:/Users/lenovo/Desktop/new.png";
		String iconPath = "src/sources/logo.png";
		String markContent = "力德 优能天才";
		String fontType = "微软雅黑";
		Color color = Color.GRAY;
		int fontSize = 20;
		int width = 864;
		int height = 200;
		int w = 10;
		int h = 10;
		float alpha = 0.8f;
		
		try {
			zipImageFile(sourceFilePath, targetFilePath, width, height);
			zipWidthHeightImageFile(sourceFilePath, targetFilePath, width, height);
			markImageByIcon(sourceFilePath, targetFilePath, iconPath, w, h, alpha);
			markImageByString(sourceFilePath, targetFilePath, markContent, fontType, fontSize, w, h, color);
			zipImageAndMarkString(sourceFilePath, targetFilePath, markContent, fontType, fontSize, w, h, color, width, height);
			zipImageAndMarkIcon(sourceFilePath, targetFilePath, iconPath, w, h, alpha, width, height);
			zipWidthHeightImageAndMarkString(sourceFilePath, targetFilePath, markContent, fontType, fontSize, w, h, color, width, height);
			zipWidthHeightImageAndMarkIcon(sourceFilePath, targetFilePath, iconPath, w, h, alpha, width, height);
		} catch (Exception e) {
			e.printStackTrace();
		}  
	}
}
